package controllers

import (
	"fly/resp"
	"fly/schema"
	"github.com/beego/beego/v2/core/logs"
	"github.com/beego/beego/v2/core/validation"
	beego "github.com/beego/beego/v2/server/web"
	"github.com/duke-git/lancet/v2/condition"
	"github.com/duke-git/lancet/v2/convertor"
	"github.com/pkg/errors"
	"github.com/smartystreets/assertions"
)

type BaseController struct {
	beego.Controller
}

// GetReqUserId
// 当前请求的userId
func (c *BaseController) GetReqUserId() int64 {
	userId := c.Ctx.Input.Param(schema.KeyAuthTokenUserId)
	id, _ := convertor.ToInt(userId)
	return id
}

// CheckErrorAbort
// 异常处理-若err不为nil,拦截并异常响应
func (c *BaseController) CheckErrorAbort(err *schema.WrapError) {
	if err != nil && err.Err != nil {
		cause := errors.WithStack(err.Err)
		logs.Error("check error and abort cause>> %+v", cause)
		c.Data["json"] = resp.StatusResult{
			Code:    err.Code,
			Status:  schema.FailStatus,
			TraceId: c.Ctx.Request.Header.Get(schema.TrackKey),
			Message: err.Err.Error(),
		}
		_ = c.ServeJSON()
		panic("Abort")
	}
}

// CheckReqErrorAbort
// 异常处理-若请求相关的err不为nil,拦截并异常响应
func (c *BaseController) CheckReqErrorAbort(err error) {
	c.CheckErrorAbort(schema.Wrap(schema.ErrRequestCode, err))
}

// CheckRespErrorAbort
// 异常处理-若处理响应相关的err不为nil,拦截并异常响应
func (c *BaseController) CheckRespErrorAbort(err error) {
	c.CheckErrorAbort(schema.Wrap(schema.FailCode, err))
}

// CheckAssertAbort
// 异常处理-通过断言处理后失败时拦截并异常响应
func (c *BaseController) CheckAssertAbort(data interface{}, msg string) {
	assertResult := assertions.ShouldNotBeNil(data)
	if len(assertResult) > 0 {
		c.CheckErrorAbort(schema.Wrap(schema.ExceptionCode, errors.New(condition.TernaryOperator(len(msg) > 0, msg, assertResult))))
	}
}

// ValidReqParams
// 检查验证请求参数
func (c *BaseController) ValidReqParams(params interface{}) {
	valid := validation.Validation{}
	// 设置自定义提示信息
	//validation.SetDefaultMessage()
	b, err := valid.Valid(params)
	c.CheckReqErrorAbort(err)
	if !b {
		errs := make(map[string]string)
		for _, er := range valid.Errors {
			errs[er.Key] = er.Message
		}
		c.CheckErrorAbort(schema.Wrap(schema.ErrRequestCode, errors.New(convertor.ToString(errs))))
	}
}

// Success
// 成功处理
func (c *BaseController) Success(data interface{}) {
	traceID := c.Ctx.Request.Header.Get(schema.TrackKey)
	// 使用c.JSONResp无法打印日志里的body
	//_ = c.JSONResp(resp.StatusResult{
	//	Code:    resp.SuccessCode,
	//	Status:  resp.OKStatus,
	//	TraceId: traceID,
	//	Content:    &data,
	//})
	c.Data["json"] = resp.StatusResult{
		Code:    schema.SuccessCode,
		Status:  schema.OKStatus,
		TraceId: traceID,
		Content: &data,
	}
	_ = c.ServeJSON()
}

func (c *BaseController) Ok(message ...string) {
	if len(message) > 0 {
		c.Success(message[0])
	} else {
		c.Success("ok")
	}
}

// Complete
// 异常处理-若处理响应相关的err不为nil,拦截并异常响应
func (c *BaseController) Complete(data interface{}, err error) {
	if err != nil {
		c.CheckErrorAbort(schema.Wrap(schema.FailCode, err))
	} else {
		c.Success(data)
	}
}
